package com.luckyframe.project.jmeter.execution.testcase;

import com.luckyframe.project.jmeter.consumer.watch.CaseWatchTask;
import com.luckyframe.project.jmeter.execution.TestStateListener;
import com.luckyframe.project.jmeter.jmeterTestCase.domain.JmeterTestCase;
import com.luckyframe.project.jmeter.jmeterTestPlan.context.TestPlanListener;
import com.luckyframe.project.jmeter.jmeterTestPlan.domain.JmeterTestPlan;
import com.luckyframe.project.jmeter.jmeterTestPlan.domain.PlanCaseTaskGroup;
import org.apache.jmeter.control.TransactionController;
import org.apache.jmeter.report.core.Sample;
import org.apache.jmeter.report.core.SampleMetadata;
import org.apache.jmeter.reporters.ResultCollector;
import org.apache.jmeter.samplers.SampleEvent;
import org.apache.jmeter.samplers.SampleResult;
import org.apache.jmeter.samplers.SampleSaveConfiguration;
import org.apache.jmeter.save.CSVSaveService;

import java.util.concurrent.BlockingQueue;
import java.util.concurrent.LinkedBlockingQueue;

/**
 * 测试用例监听器
 */
public class TestCaseListener extends ResultCollector implements TestStateListener {

    private JmeterTestPlan plan;

    private JmeterTestCase testCase;

    private PlanCaseTaskGroup caseTaskGroup;

    private long row=0;

    private BlockingQueue<Sample> samples=new LinkedBlockingQueue<>();

    private CaseWatchTask caseWatchTask;

    private TestPlanListener testPlanListener;

    public TestCaseListener(JmeterTestPlan plan, JmeterTestCase testCase, TestPlanListener testPlanListener) {
        this.plan = plan;
        this.testCase = testCase;
        this.testPlanListener = testPlanListener;
    }

    @Override
    public void testStarted() {

        if(caseWatchTask==null){
            caseWatchTask= new CaseWatchTask(plan,testCase,samples);
            caseWatchTask.start();
        }

        testPlanListener.testStarted();
    }

    @Override
    public void testStarted(String host) {

    }

    @Override
    public void testEnded() {
        if(caseWatchTask!=null){
            caseWatchTask.stop();
        }

        caseTaskGroup.caseFinished();
        testPlanListener.decreaseTask();

    }

    @Override
    public void testEnded(String host) {

    }


    @Override
    public void testFailed(Throwable e) {
        caseTaskGroup.caseFailed(e);
        testPlanListener.decreaseTask();

    }


    @Override
    public void sampleOccurred(SampleEvent e) {

        super.sampleOccurred(e);

        SampleResult result = e.getResult();

        if (isSampleWanted(result.isSuccessful())){
            SampleResult s = e.getResult();

            if( TransactionController.isFromTransactionController(s)) {
                return;
            }

            SampleMetadata sampleMetadata = new SampleMetadata(
                    SampleSaveConfiguration.staticConfig());

            String delimitedResult = CSVSaveService.resultToDelimitedString(e);
            String[] data = delimitedResult.split(",");

            Sample sample =new Sample (row++,sampleMetadata,data);
            samples.offer(sample);
            testPlanListener.addSample(sample);
        }
    }


    public void setCaseTaskGroup(PlanCaseTaskGroup caseTaskGroup) {
        this.caseTaskGroup = caseTaskGroup;
    }
}
